using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public sealed class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    [SerializeField]
    private RectTransform joystick;
    [SerializeField]
    private RectTransform joystickBG;
    public Vector2 joystickVec;
    public bool isMove = false;
    private Vector2 joystickTouchPos;
    private Vector2 joystickOriginalPos;
    private float joystickRadius;

    public bool isFollowFingerMode = false;
    private Vector3 lastDrapPos;
    private bool isPointDown;
    public float followFingerMoveSpeed;

    private CanvasGroup group;

    public Camera cam;

    private void Start()
    {
        joystickOriginalPos = joystickBG.transform.position;
        joystickRadius = joystickBG.sizeDelta.y / 2;
        group = GetComponent<CanvasGroup>();
        if (group != null)
            ChangeCanvasGroup(0f);
    }

    public void SetFollowFingerMode(bool flag)
    {
        isFollowFingerMode = flag;
        joystick.gameObject.SetActive(!flag);
        joystickBG.gameObject.SetActive(!flag);
    }

    public void OnPointerDown(PointerEventData pointerEventData)
    {
        var wpos = pointerEventData.position;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(transform as RectTransform, wpos, cam, out var pos);
        joystickBG.localPosition = pos;
        joystickTouchPos = pos;
        isPointDown = true;
        if (isFollowFingerMode)
        {
            lastDrapPos = Input.mousePosition;
        }
        ChangeCanvasGroup(1.0f);
        OnDrag(pointerEventData);
    }

    public void OnDrag(PointerEventData pointerEventData)
    {
        if (isFollowFingerMode)
        {
            
        }
        else
        {
            var wpos = pointerEventData.position;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(transform as RectTransform, wpos, cam, out var pos);
            joystickVec = (pos - joystickTouchPos).normalized;
            isMove = true;
            float joystickDist = Vector2.Distance(pos, joystickTouchPos);
            Vector2 localPosition;
            if (joystickDist < joystickRadius)
            {
                localPosition = joystickTouchPos + joystickVec * joystickDist;
            }
            else
            {
                localPosition = joystickTouchPos + joystickVec * joystickRadius;
            }
            joystick.localPosition = localPosition;
            // 小范围操作时速度减半
            var slowDist = joystickRadius * 0.6f;
            if (joystickDist < slowDist)
            {
                joystickVec *= 0.5f + 0.4f * joystickDist / slowDist;
            }
        }
    }


    public void OnPointerUp(PointerEventData eventData)
    {
        joystickVec = Vector2.zero;
        joystick.position = joystickOriginalPos;
        joystickBG.position = joystickOriginalPos;
        isMove = false;
        isPointDown = false;
        followFingerMoveSpeed = 0;
        ChangeCanvasGroup(0f);
    }

    void ChangeCanvasGroup(float value)
    {
        group.alpha = value;
    }

    private void Update()
    {
        if (isFollowFingerMode && isPointDown)
        {
            var wpos = Input.mousePosition;
            var diff = (wpos - lastDrapPos);
            lastDrapPos = wpos;
            var dist = diff.magnitude;
            if (dist > float.Epsilon)
            {
                isMove = true;
                joystickVec = diff / dist;
                followFingerMoveSpeed = dist * 0.01f / Time.deltaTime;
            }
            else
            {
                isMove = false;
                followFingerMoveSpeed = 0;
            }
        }
    }
}